home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / comm2 / mmbndlfl.lha / MM / Rexx / MM_BundleFiles.rexx < prev    next >
OS/2 REXX Batch file  |  1996-05-10  |  22KB  |  1,020 lines

  1. /*
  2.  
  3.                      $VER: MM_BundleFiles 0.20  (10.05.96)
  4.  
  5.                             (C) 1996 Robert Hofmann
  6.  
  7. */
  8.  
  9. parse arg args
  10.  
  11. options cache
  12. options failat 99
  13. options results
  14.  
  15. signal on break_c
  16. signal on break_d
  17. signal on break_e
  18. signal on break_f
  19. signal on halt
  20. signal on ioerr
  21. signal on syntax
  22.  
  23. address 'MAILMANAGER'
  24.  
  25.  
  26. Main:
  27.  
  28.     call Init
  29.     call Header
  30.     call Parse_Args(strip(args))
  31.     call Read_Cfg
  32.     call Wait_AreasWindow
  33.  
  34.     call Command('c:delete >NIL:' system.tmpdir 'all quiet force noreq')
  35.     if ~makedir(strip(system.tmpdir, 't', '/'))    then call Quit(30, 'Unable to create tmpdir "'system.tmpdir'"!')
  36.  
  37.     if system.arg.arc    then    call Arc_Files
  38.     else                                        call Unarc_Files
  39.  
  40.     if exists(system.tmpdir) then call Command('c:delete >NIL:' system.tmpdir 'all quiet force noreq')
  41.     call delete(system.tmpfile)
  42.  
  43. call Quit(0, 'All done.')
  44. exit
  45.  
  46.  
  47. Add_Arc: procedure Expose arc. system.
  48.  
  49.     parse arg filename, del
  50.  
  51.     MM_AddToStem 'arc.f.name'     'filename'
  52.     MM_AddToStem 'arc.f.delete'    'del'
  53.  
  54. return
  55.  
  56.  
  57. Add_Flow: procedure Expose new. system.
  58.  
  59.     parse arg file . 1 pfx 2 .
  60.  
  61.     if system.sortflows then
  62.         if pos(pfx, '-^#')>0    then    stem    = 'new.first'
  63.         else                                                stem    = 'new.last'
  64.     else                                                    stem    = 'new'
  65.  
  66.     MM_AddToStem stem 'file'
  67.  
  68. return
  69.  
  70.  
  71. Arc_FlowFiles: procedure Expose system.
  72.  
  73.     arg address, flowname, arcname, type, archiver, extension
  74.     flow            = flowname || type
  75.     full_flow    = system.mm.outbound || flow
  76.     flow_tmp    = full_flow'.tmp'
  77.     test            = system.arg.test
  78.     test.0        = ''
  79.     test.1        = '.test'
  80.     check            = 0
  81.  
  82.     if open(in, full_flow, a) then
  83.         if rename(full_flow, flow_tmp) then check    = 1
  84.  
  85.     call close(in)
  86.  
  87.     if ~check then
  88.         do
  89.       call Log('  *** WARNING: Unable to lock or rename "'full_flow'" to "'flow_tmp'"!')
  90.             return
  91.         end
  92.  
  93.     MM_ReadStem flow_tmp 'files'
  94.  
  95.     arc.    = 0
  96.     new.    = 0
  97.  
  98.     do n=0 to files.count-1
  99.         check    = left(files.n, 1)
  100.  
  101.         parse value upper(reverse(files.n)) with ext '.' .
  102.         ext        = reverse(ext)
  103.  
  104.         select
  105.             when check='#' | ext='PKT' | index(system.bundle_exts, ext)>0 then call Add_Flow(files.n)
  106.             when check='~' then iterate
  107.  
  108.             otherwise
  109.                 do
  110.                     file    = strip(files.n, 'l', '-^')
  111.                     force    = Check_ForceArc(file)
  112.  
  113.                     if force=0 then    parse value statef(file)'0 0' with . size .
  114.                     else                        size    = 1
  115.  
  116.                     if size>0 & (force>0 | (size+512)%1024<system.maxfilesize) then
  117.                         call Add_Arc(file, force=2)
  118.                     else call Add_Flow(files.n)
  119.                 end
  120.         end
  121.     end
  122.  
  123.     if arc.f.name.count>0 then
  124.         do
  125.             call Command('c:delete >NIL:' system.tmpdir'#? all quiet force noreq')
  126.  
  127.             do n=0 to arc.f.name.count-1
  128.                 tmp    = BaseName(arc.f.name.n)
  129.  
  130.                 call Log('  -> Adding "'tmp'"',, 3)
  131.  
  132.                 MM_CopyFile arc.f.name.n system.tmpdir || tmp
  133.                 if RC~=0    then
  134.                     if ~exists(arc.f.name.n) then call Log('  *** WARNING: "'arc.f.name.n'" does not exist!')
  135.                     else
  136.                         do
  137.                             call Add_Flow(arc.f.name.n)
  138.               call Log('  *** WARNING: Unable to copy "'arc.f.name.n'" to "'system.tmpdir'"!!!')
  139.                         end
  140.             end
  141.  
  142.             old_cd        = pragma('d', system.tmpdir)
  143.             arc_file    = system.mm.bundledir || arcname || extension
  144.  
  145.             call Log('  => Arcing files to' arc_file'...')
  146.  
  147.             if Command(system.cmd.archiver.arc arc_file '#?', 1)=0    then
  148.                 do
  149.                     tmp    = 'To' address
  150.                     MM_SetFilenote arc_file 'tmp'
  151.  
  152.                     do n=0 to arc.f.name.count-1
  153.                         if ~arc.f.delete.n    then iterate
  154.  
  155.                         call Log('  -> Deleting "'arc.f.name.n'"',, 5)
  156.                         if ~test then
  157.                             if ~delete(arc.f.name.n) then call Log('  *** WARNING: Unable to delete "'arc.f.name.n'"!')
  158.                     end
  159.  
  160.                     if system.sortflows then    stem    = 'new.first'
  161.                     else                                            stem    = 'new'
  162.  
  163.                     ret.    = 0
  164.                     MM_SearchInStem stem 'ret' '"?'arc_file'"' 'NUM'
  165.                     if ret.count=0    then    call Add_Flow('^'arc_file)
  166.  
  167.                     call Write_Flow(flow_tmp || test.test)
  168.                 end
  169.  
  170.             call Log('  Cleaning up...',, 5)
  171.             call pragma('d', old_cd)
  172.             call Command('c:delete >NIL:' system.tmpdir'#? all quiet force noreq')
  173.  
  174.         end
  175.     else call Log('  -> Nothing to do...',, 4)
  176.  
  177.     if ~rename(flow_tmp, full_flow)    then call Quit(30, 'Unable to rename "'flow_tmp'" to "'full_flow'"!')
  178.  
  179. return
  180.  
  181.  
  182. Arc_Files: procedure Expose system.
  183.  
  184.     call Log(' Reading index...',, 4)
  185.     MM_ReadStem system.prg.idx 'system.idx'
  186.  
  187.     do n=0 to system.arc.node.count-1
  188.         parse var system.arc.node.n zone ':' net '/' nd '.' point '@' .
  189.  
  190.         type            = word('* C D F H', find('VIRTUAL CRASH DIRECT NORMAL HOLD', system.arc.flavor.n))'LO'
  191.         flow            = zone'.'net'.'nd'.'point'.'
  192.         full_flow    = system.mm.outbound || flow || type
  193.  
  194.         call Log(' Checking flow "'flow || type'"...')
  195.  
  196.         parse value statef(full_flow)'0 0 0 0 0 0' with . size . . date time .
  197.  
  198.         if size>0    then
  199.             if Check_Flow(flow || type, size date time) then
  200.                 do
  201.                     tmp    = system.arc.arcer.n
  202.                     call Arc_FlowFiles(system.arc.node.n, flow, system.arc.name.n'.', type, tmp, system.cmd.tmp.extension)
  203.                 end
  204.             else    call Log('  -> No changes since last scan.',, 4)
  205.         else        call Log('  -> No flow found.',, 4)
  206.     end
  207.  
  208.     call Log(' Writing index...',, 4)
  209.     MM_WriteStem system.prg.idx 'system.idx'
  210.     if RC~=0 then call Quit(35, 'Unable to write "'system.prg.idx'"!!!')
  211.  
  212. return
  213.  
  214.  
  215. BaseName: procedure
  216.  
  217.     parse arg file
  218.  
  219.     p    = max(lastpos(':', file), lastpos('/', file))
  220.  
  221.     if p=0    then    ret = file
  222.     else                    ret    = substr(file, p+1)
  223.  
  224. return ret
  225.  
  226.  
  227. break_c:; break_d:; break_e:; break_f:; halt:
  228.  
  229.     signal off break_c
  230.     signal off break_d
  231.     signal off break_e
  232.     signal off break_f
  233.     signal off halt
  234.  
  235.     return_code        =    5
  236.     error_line    = 0
  237.     error_msg            = 'Execution halted!!!'
  238.     rc                        = 0
  239. signal Exit
  240.  
  241.  
  242. Check_Flow: procedure Expose system.
  243.  
  244.     arg flow, check
  245.  
  246.     line    = flow check
  247.     ret.    = 0
  248.  
  249.     MM_SearchInStem 'system.idx' 'ret' '"'flow' #?"' 'NUM'
  250.  
  251.     if ret.count=0 then
  252.         do
  253.             MM_AddToStem 'system.idx' 'line'
  254.             ret    = 1
  255.         end
  256.     else
  257.         do
  258.             nr                        = ret.0
  259.             ret                        = system.idx.nr~=line
  260.             system.idx.nr    = line
  261.         end
  262.  
  263. return ret
  264.  
  265.  
  266. Check_ForceArc: procedure Expose system.
  267.  
  268.     parse arg stem.0
  269.     stem.count    = 1
  270.  
  271.     do n=0 to system.forcearc.pattern.count-1
  272.         ret.    = 0
  273.         MM_SearchInStem 'stem' 'ret' '"'system.forcearc.pattern.n'"' 'NUM'
  274.         if ret.count>0 then return 1+(find(system.forcearc.delete, system.forcearc.pattern.n)>0)
  275.     end
  276.  
  277. return 0
  278.  
  279.  
  280. Command: procedure Expose system.
  281.  
  282.     parse arg cmd, log
  283.  
  284.     if log=''    then log=5
  285.  
  286.     address command cmd
  287.  
  288.     if rc>log then call Log('*** ERROR: Command "'cmd'" returned' rc'.')
  289. return rc
  290.  
  291.  
  292. Exit:
  293.  
  294.     select
  295.         when return_code>=40 then error = 'INTERNAL-ERROR:'
  296.         when return_code>=30 then error = 'IO-ERROR:'
  297.         when return_code>=20 then error = 'ERROR:'
  298.         when return_code>=10 then error = 'WARNING:'
  299.         when return_code>=5  then error = 'INFO:'
  300.         otherwise                                    error = ''
  301.     end
  302.  
  303.   call Log()
  304.     call Log('***' strip(error error_msg) '***', '+')
  305.     call Log(,'\')
  306.  
  307.     call setclip('MM_LogPre', system.mm.logpre)
  308.  
  309. exit return_code
  310.  
  311.  
  312. Get_Arg: procedure Expose args cfg. system.
  313.  
  314.   arg keyword, mode, old
  315.  
  316.     uargs    = upper(args)
  317.     p            = find(uargs, keyword)
  318.  
  319.     if p=0    then
  320.         do
  321.             p = pos(' 'keyword'=', ' 'uargs)
  322.  
  323.             if p>0 then    args    = overlay(' ', args, p+length(keyword))
  324.  
  325.       p = find(upper(args), keyword)
  326.         end
  327.  
  328.     system.cmdopt.keyword    = p>0
  329.  
  330.     select
  331.         when mode=0    then
  332.             if p>0 then
  333.                 do
  334.                     ret        = 1
  335.                     args    = delword(args, p, 1)
  336.                 end
  337.             else ret    = old
  338.  
  339.         when mode=1 then
  340.             if p>0 then
  341.                 do
  342.                     left    = subword(args, 1, p-1)
  343.                     rest    = subword(args, p+1)
  344.  
  345.                     if left(rest, 1)='"' then    parse var rest . '"'    ret '"'    rest
  346.                     else                                            parse var rest                ret            rest
  347.  
  348.                     args    = strip(left strip(rest))
  349.                 end
  350.             else ret    = old
  351.  
  352.         when mode=2 then
  353.             do
  354.                 if left(args, 1)='"'    then    parse var args . '"'    ret '"'    args
  355.                 else                                                parse var args                ret         args
  356.  
  357.                 if strip(ret)=''            then    ret = old
  358.             end
  359.  
  360.         otherwise exit 99
  361.     end
  362.  
  363.     args    = strip(args)
  364.     ret        = strip(ret, 'b', '" ')
  365.  
  366. return ret
  367.  
  368.  
  369. Get_Version: procedure
  370.  
  371.     parse arg mode
  372.  
  373.     parse value sourceline(3-mode) with . . ver .
  374.     parse var ver tst 'ß' .
  375.  
  376.     if ~datatype(strip(tst, 'b', '/c '), 'N') then
  377.         if ~mode then ver = Get_Version(1)
  378.         else exit 99
  379.  
  380. return ver
  381.  
  382.  
  383. Header:
  384.  
  385.     call Log(,'/')
  386.     call Log('***' system.prg.id '***', '+')
  387.     call Log(' 'system.prg.cr)
  388.     call Log()
  389.  
  390. return
  391.  
  392.  
  393. Init:
  394.  
  395.     system.                        = 0
  396.  
  397.     system.prg.ver        = Get_Version(0)
  398.     system.prg.name        = 'MM_BundleFiles'
  399.     system.prg.id            = system.prg.name 'v'system.prg.ver
  400.     system.prg.cpfx        = 'MM:Config/'system.prg.name'.'
  401.     system.prg.cfg        = system.prg.cpfx'cfg'
  402.     system.prg.idx        = system.prg.cpfx'idx'
  403.     system.prg.script    = 'MM:Rexx/'system.prg.name'.rexx'
  404.     system.prg.cr            = '(C) 1996 Robert Hofmann'
  405.     system.tmpfile        = 'T:'system.prg.name'.tmp'
  406.     system.invalid        = xrange('0'x, '@') || xrange('[', 'FF'x)
  407.     system.replace        = copies('_', length(system.invalid))
  408.     system.mm.logpre     = getclip('MM_LogPre')
  409.     system.prg.logpre    = system.mm.logpre'|'
  410.     call                                setclip('MM_LogPre', system.prg.logpre)
  411.     system.cmdopts        = 'ARC/S,UNARC/S,CPLCFG/S,TEST/S'
  412.  
  413.     MM_GetCfgPaths            'system.mm'
  414.  
  415.     MM_Version                    'system.mm'
  416.     if system.mm.version<1.2 then call Quit(20, 'You need at least MM v1.2 to run this script!')
  417.  
  418.     call Include_Lib('rexxsupport')
  419. return
  420.  
  421.  
  422. Include_Lib: procedure Expose system.
  423.  
  424.     parse arg lib, prio
  425.     if right(upper(lib), 8)~='.LIBRARY' then lib    = lib'.library'
  426.     if prio=''                                                    then prio    = 0
  427.  
  428.     if ~show('l', lib) then
  429.         if ~addlib(lib, prio, -30, 0) then call Quit(20, 'Could not open' lib'!!!')
  430.  
  431. return
  432.  
  433.  
  434. IOerr:
  435.  
  436.     signal off ioerr
  437.  
  438.     return_code        = 20
  439.     error_line    = sigl
  440.     error_msg            = 'IO-error' rc 'at line' sigl '['errortext(rc)']')
  441.     rc                        = 0
  442. signal Exit
  443.  
  444.  
  445. Log: procedure Expose system.
  446.  
  447.     parse arg text, pre, level
  448.  
  449.     if ~datatype(level, 'N') then level = system.prg.loglevel
  450.  
  451.     tmp        = word('PRG MM', (pre~='')+1)
  452.     text    = system.tmp.logpre || pre' 'text
  453.  
  454.     MM_WriteLog 'text' level
  455. return
  456.  
  457.  
  458. Make_Valid: procedure Expose system.
  459.  
  460.     arg string
  461.  
  462. return translate(string, system.replace, system.invalid)
  463.  
  464.  
  465. Parse_Args: procedure Expose system.
  466.  
  467.     parse arg args
  468.  
  469.     tpl        = system.cmdopts',?/S'
  470.     args    = translate(args, '  ', '9'x'=')
  471.  
  472.     pk        = pos('/K', tpl)
  473.     ps        = pos('/S', tpl)
  474.  
  475.     select
  476.         when pk=0    & ps=0    then    p    = 0
  477.         when pk=0 & ps>0    then  p    = ps
  478.         when ps=0 & pk>0    then    p    = pk
  479.         otherwise                                p    = min(pk, ps)
  480.     end
  481.  
  482.     p            = lastpos(',', left(tpl, p))
  483.     tpl        = substr(tpl, p+1) || left(tpl, max(p-1, 0))
  484.  
  485.     do while tpl~=''
  486.         parse var tpl template ',' tpl
  487.         parse var template keyword '/' .
  488.  
  489.         bool    = pos('/S',    template)>0
  490.         key        = pos('/K', template)>0
  491.         must    = pos('/A', template)>0
  492.         num        = pos('/N', template)>0
  493.  
  494.         select
  495.             when must then        system.arg.keyword    = '0'x
  496.             when bool    then        system.arg.keyword    = 0
  497.             when num    then        system.arg.keyword    = 0
  498.  
  499.             otherwise                    system.arg.keyword    = ''
  500.         end
  501.  
  502.         if bool | key    then    mode    = ~bool
  503.         else                                mode    = 2
  504.  
  505.         system.arg.keyword    = Get_Arg(keyword, mode, system.arg.keyword)
  506.  
  507.         if keyword='?' & system.arg.keyword=1 then leave
  508.  
  509.         if must & system.arg.keyword='0'x then
  510.             do
  511.                 tmp    = template 'missing!!!'
  512.  
  513.                 say
  514.                 say ' ***' tmp '***'
  515.  
  516.                 signal Usage
  517.             end
  518.  
  519.         if num & ~datatype(system.arg.keyword, 'N') then
  520.             if ~must & system.arg.keyword='' then    system.arg.keyword    = 0
  521.             else
  522.                 do
  523.                     tmp    = 'Numeric value expected for' template', but is "'system.arg.keyword'"!!!'
  524.  
  525.                     say
  526.                     say ' ***' tmp '***'
  527.  
  528.                     signal Usage
  529.                 end
  530.     end
  531.  
  532.     tmp    = '?'; if system.arg.tmp then signal Usage
  533.  
  534.     if args~='' then call Quit(10, 'Unknown option(s):' args)
  535.  
  536.  
  537.     if ~system.arg.arc & ~system.arg.unarc    then call Quit(11, 'Too few arguments!')
  538.     if system.arg.arc & system.arg.unarc        then call Quit(12, 'Too many arguments!')
  539.  
  540. return
  541.  
  542.  
  543. Path: procedure
  544.  
  545.     parse arg path
  546.  
  547.     tmp    = right(path, 1)
  548.  
  549.     if tmp~='/' & tmp~=':' then path = path'/'
  550. return path
  551.  
  552.  
  553. Quit:
  554.  
  555.     parse arg return_code, error_msg
  556.  
  557.     error_line    = 0
  558.     rc                        = 0
  559. signal Exit
  560.  
  561.  
  562. Request_Choice: procedure Expose system.
  563.  
  564.     parse arg text, buttons, ret_vals
  565.  
  566.     title    = system.prg.name'-Requester'
  567.     text    = translate(Replace(text, '0A'x, '\n'), '1b'x, '\')
  568.  
  569.     if length(text)<40 then text = center(text, 40)
  570.  
  571.     MM_Requester title 'text' 'buttons'
  572.  
  573.     if rc=0 then rc=words(ret_vals)
  574.  
  575. return compress(word(ret_vals, rc), '_')
  576.  
  577.  
  578. Replace: procedure
  579.  
  580.     parse arg string, new, old
  581.  
  582.     do while index(string, old) ~= 0
  583.         interpret "parse var string l '"old"' r"
  584.         string = l || new || r
  585.     end
  586.  
  587. return string
  588.  
  589.  
  590. Syntax:
  591.  
  592.     signal off syntax
  593.  
  594.     return_code        = 40
  595.     error_line    = sigl
  596.     error_msg            = 'Syntax-error' rc 'at line' sigl '['errortext(rc)']'
  597.     rc                        = 0
  598. signal Exit
  599.  
  600.  
  601. Unarc_Files: procedure Expose system.
  602.  
  603.     test    = system.arg.test
  604.  
  605.     call Log(' Searching for filebundles...')
  606.  
  607.     call Command('c:list >'system.tmpfile system.mm.inbound 'p' system.unarc.pattern 'lformat "%n"')
  608.  
  609.     MM_ReadStem system.tmpfile 'found'
  610.  
  611.     if found.count=0    then call Log('  No filebundles found...')
  612.     else
  613.         do
  614.             old_cd    = pragma('d', system.tmpdir)
  615.  
  616.             do n=0 to found.count-1
  617.                 call Log('  Unarcing' found.n'...')
  618.  
  619.                 parse value upper(reverse(found.n)) with ext '.' basename
  620.                 basename    = reverse(basename)
  621.                 ext                = reverse(ext)
  622.                 arcer            = system.syn.ext
  623.                 full_file    = system.mm.inbound || found.n
  624.  
  625.                 ret                = Command(system.cmd.arcer.unarc full_file)>0
  626.  
  627.                 if ret>0    then
  628.                     do
  629.                         MM_CopyFile full_file system.mm.baddir'BAD_'found.n
  630.                         call Log('  *** WARNING: Error' ret 'while unarcing "'found.n'", moved to "'system.mm.baddir'"!')
  631.                     end
  632.                 else
  633.                     if ~test then
  634.                         if system.backup    then    MM_MoveFile full_file system.mm.backupdir || found.n
  635.                         else                                        call delete(full_file)
  636.  
  637.                 call Command('c:list >'system.tmpfile system.tmpdir'#? all files lformat "%p %n"')
  638.  
  639.                 files.    = 0
  640.                 MM_ReadStem system.tmpfile 'files'
  641.  
  642.                 do m=0 to files.count-1
  643.                     parse var files.m dir name .
  644.                     tmp = dir || name
  645.  
  646.                     call Log('   -> Extracted "'name'"',, 4)
  647.  
  648.                     if test then iterate
  649.  
  650.                     MM_MoveFile tmp system.mm.inbound || name
  651.                     if RC~=0 then call Quit(34, 'Unable to move "'tmp'" to "'system.mm.inbound'"!')
  652.                 end
  653.             end
  654.  
  655.             call pragma('d', old_cd)
  656.             call Command('c:delete' system.tmpdir'/#? all quiet force noreq')
  657.         end
  658.  
  659. return
  660.  
  661.  
  662. Usage:
  663.  
  664.     rx.            = ''
  665.     rx.0.0    = '[rx] '
  666.     rx.0.1    = '[.rexx]'
  667.     m                =    pos('/e', system.prg.ver)>0
  668.  
  669.     say
  670.     say 'Usage:' rx.m.0 || system.prg.name || rx.m.1 system.cmdopts
  671.     say
  672. call Quit(0, 'Usage requested.')
  673.  
  674.  
  675. Wait_AreasWindow: procedure Expose system.
  676.  
  677.     MM_AreasWin
  678.     if rc=0 then return
  679.  
  680.     bell    = '07'x
  681.     cr        = '0D'x
  682.  
  683.     if Request_Choice('\c\n\1'system.prg.id'\0 is waiting.\n\nPlease go back to the Areas-Window as soon as possible!\n',,
  684.                                         '* _WAIT | _QUIT ', '0 1') then call Quit(5, 'Aborted by user.')
  685.  
  686.     tmp        = 'Waiting for Areas-Window...'
  687.     call writech(STDOUT, bell || tmp || cr)
  688.     call Log(tmp,, 4)
  689.  
  690.     rc    = 1
  691.  
  692.     do while rc~=0
  693.         MM_AreasWin
  694.  
  695.         call writech(STDOUT, bell)
  696.         call Delay(250)
  697.     end
  698.  
  699. return
  700.  
  701.  
  702. Write_Flow: procedure Expose new. system.
  703.  
  704.     parse arg flow
  705.  
  706.   if system.sortflows then
  707.         do
  708.             MM_WriteStem flow 'new.first'
  709.             MM_WriteStem flow 'new.last' 'APPEND'
  710.         end
  711.     else
  712.             MM_WriteStem flow 'new'
  713.  
  714. return
  715.  
  716.  
  717.  
  718.                 /********** Config related routines **********/
  719.  
  720.  
  721.  
  722. Add_Cfg: procedure Expose cpl. system.
  723.  
  724.     parse arg var, val, add
  725.     upper var
  726.  
  727.     if datatype(val, 'N') & add=''    then    q        = ''
  728.     else                                                                    q        = "'"
  729.  
  730.     line    = var'='q || translate(val, 'ø¶', '2227'x) || q || add
  731.  
  732.     MM_AddToStem 'cpl' 'line'
  733.  
  734.     interpret line
  735.  
  736. return
  737.  
  738.  
  739. Add_Cfg_Stem: procedure Expose cpl. system.
  740.  
  741.     parse arg stem, value
  742.     upper stem
  743.  
  744.     MM_AddToStem stem 'value'
  745.  
  746.     if find(cpl.stems, stem)=0 then cpl.stems = cpl.stems stem
  747.  
  748. return
  749.  
  750.  
  751. Add_Script: procedure Expose script.
  752.  
  753.     parse arg line
  754.  
  755.     MM_AddToStem 'script' 'line'
  756.  
  757. return
  758.  
  759.  
  760. Compile_Cfg: procedure Expose system.
  761.  
  762.     call Log(' Reading & compiling config...')
  763.  
  764.   MM_ReadStem system.prg.cfg 'cfg'
  765.     if rc>0 then call Quit(21, 'Unable to read "'system.prg.cfg'"!')
  766.  
  767.     cpl.                      = 0
  768.     cpl.stems                    = ''
  769.     l                                    = 0
  770.     search_pattern        = ''
  771.     delete_pattern        = ''
  772.     defined_arcers        = ''
  773.  
  774.     do n=0 to cfg.count-1
  775.         parse value strip(translate(cfg.n, ' ', '9'x)) with key args ';' .
  776.         key     = upper(strip(key))
  777.         args    = strip(args)
  778.         l            = l+1
  779.  
  780.         select
  781.             when key=''                                then iterate
  782.  
  783.             when key='#ARCHIVER'            then
  784.                 do
  785.                     call Parse_Cfg_Args(args, 'ARCER/A,OFFS/A,ID/A,ARC_CMD/A,UNARC_CMD/A,EXTENSION/A', key, l)
  786.  
  787.                     upper        cfg.prm.arcer cfg.prm.extension
  788.                     stem    = 'system.cmd.'cfg.prm.arcer'.'
  789.  
  790.                     call Add_Cfg(stem'arc',                    cfg.prm.arc_cmd)
  791.                     call Add_Cfg(stem'unarc',                cfg.prm.unarc_cmd)
  792.                     call Add_Cfg(stem'extension',        cfg.prm.extension)
  793.                     call Add_Cfg_Stem('system.arc',    cfg.prm.arcer)
  794.  
  795.                     call Add_Cfg('system.syn.'cfg.prm.extension, cfg.prm.arcer)
  796.  
  797.                     search_pattern    = search_pattern'|'cfg.prm.extension
  798.                     defined_arcers    = defined_arcers cfg.prm.arcer
  799.                 end
  800.  
  801.             when key='#ARCNODE'                then
  802.                 do
  803.                     call Parse_Cfg_Args(args, 'NODE/A,ARCHIVER/K,NAME/K', key, l)
  804.  
  805.                     MM_GetNodeInfo cfg.prm.node 'ninfo'
  806.                     if RC~=0 then call Quit(11, 'No cfg found for node' cfg.prm.node 'at line' l'!')
  807.  
  808.                     if cfg.prm.archiver='' then cfg.prm.archiver    = ninfo.archiver
  809.  
  810.                     if find(defined_arcers, cfg.prm.archiver)=0    then
  811.                         call Quit(12, 'Archiver "'cfg.prm.archiver'" not defined at line' l'!')
  812.  
  813.                     if cfg.prm.name='' then
  814.                         do
  815.                             parse var cfg.prm.node zn ':' nt '/' nd '.' pt '@' .
  816.                             cfg.prm.name    = zn'.'nt'.'nd'.'pt
  817.                         end
  818.  
  819.                     call Add_Cfg_Stem('system.arc.node',        cfg.prm.node)
  820.                     call Add_Cfg_Stem('system.arc.arcer',        upper(cfg.prm.archiver))
  821.                     call Add_Cfg_Stem('system.arc.flavor',    ninfo.tickflavor)
  822.                     call Add_Cfg_Stem('system.arc.name',        upper(strip(cfg.prm.name, 'b', '.')))
  823.                 end
  824.  
  825.             when key='#BACKUP'                then
  826.                 do
  827.                     call Parse_Cfg_Args(args, 'DIR', key, l)
  828.  
  829.                     if cfg.prm.dir=''                then cfg.prm.dir = system.mm.backupdir
  830.                     if ~exists(cfg.prm.dir)    then all Quit(30, '"'cfg.prm.dir'" does not exist!')
  831.  
  832.                     call Add_Cfg('system.mm.backupdir', path(cfg.prm.dir))
  833.                     call Add_Cfg('system.backup',                1)
  834.                 end
  835.  
  836.             when key='#BUNDLEDIR'            then
  837.                 do
  838.                     call Parse_Cfg_Args(args, 'DIR/A', key, l)
  839.  
  840.                     if ~exists(cfg.prm.dir)    then all Quit(30, '"'cfg.prm.dir'" does not exist!')
  841.  
  842.                     call Add_Cfg('system.mm.bundledir', path(cfg.prm.dir))
  843.                 end
  844.  
  845.             when key='#FORCEARC'            then
  846.                 do
  847.                     call Parse_Cfg_Args(upper(args), 'PATTERN/A,DELETE/S', key, l)
  848.  
  849.                     tmp    = Replace(cfg.prm.pattern, '#?', '*')
  850.  
  851.                     call Add_Cfg_Stem('system.forcearc.pattern', tmp)
  852.                     if cfg.prm.delete then delete_pattern = delete_pattern tmp
  853.                 end
  854.  
  855.             when key='#MAXFILESIZE'        then
  856.                 do
  857.                     call Parse_Cfg_Args(args, 'KB_SIZE/A/N', key, l)
  858.                     call Add_Cfg('system.maxfilesize', cfg.prm.kb_size)
  859.                 end
  860.  
  861.             when key='#SORTFLOWS'            then call Add_Cfg('system.sortflows', 1)
  862.             when key='#NOSORTFLOWS'        then nop
  863.  
  864.             when key='#TMPDIR'                then
  865.                 do
  866.                     call Parse_Cfg_Args(args, 'DIR/A', key, l)
  867.  
  868.                     if ~exists(cfg.prm.dir)    then all Quit(30, '"'cfg.prm.dir'" does not exist!')
  869.  
  870.                     call Add_Cfg('system.mm.workdir', path(cfg.prm.dir))
  871.                 end
  872.  
  873.             otherwise call Quit(10, 'Unknown keyword "'key'" at line' l'!!!')
  874.         end
  875.     end
  876.  
  877.     call Add_Cfg('system.forcearc.delete',    delete_pattern)
  878.     call Add_Cfg('system.unarc.pattern',         '#?.('strip(search_pattern, 'b', '|')')')
  879.     call Add_Cfg('system.bundle_exts',             strip(translate(search_pattern, ' ', '|')))
  880.     call Add_Cfg('system.tmpdir',                        system.mm.workdir || system.prg.name'/')
  881.  
  882.  
  883.     do until cpl.stems=''
  884.         parse var cpl.stems stem cpl.stems
  885.         stem = strip(stem)
  886.         if stem='' then iterate
  887.  
  888.         code    = "do n=0 to" stem".count-1; call Add_Cfg('"stem".'n," stem".n); end;",
  889.                         "call Add_Cfg('"stem".count'," stem".count)"
  890.  
  891.         interpret code
  892.     end
  893.  
  894.     MM_SortStem 'cpl'
  895.  
  896.   MM_ReadStem            system.prg.script 'script'
  897.     MM_SearchInStem    'script' 'tmp' 'Cfg:' 'NUM'
  898.  
  899.     if tmp.count=0 then call Quit(22, system.prg.script 'was modified or not found! Please read the docs!')
  900.  
  901.     script.count    = tmp.0+1
  902.  
  903.     call Add_Script()
  904.  
  905.     line    = '9'x
  906.  
  907.     do n=0 to cpl.count-1
  908.         tmp    = strip(cpl.n)
  909.  
  910.         if length(line tmp)>=1024    then
  911.             do
  912.                 call Add_Script(strip(line, 't', '; '))
  913.                 line    = '9'x
  914.             end
  915.  
  916.         line    = line || tmp';'
  917.     end
  918.  
  919.     if length(line)>2 then call Add_Script(strip(line, 't', '; '))
  920.  
  921.     call Add_Script()
  922.     call Add_Script('return')
  923.     call Add_Script()
  924.  
  925.     MM_WriteStem    system.prg.script    'script'
  926.   MM_CRCFile        system.prg.cfg         'cfg_crc'
  927.   MM_CRCFile        system.prg.script    'scr_crc'
  928.  
  929.     tmp = c2x(system.prg.ver) cfg_crc scr_crc
  930.  
  931.     MM_SetFileNote    system.prg.script    'tmp'
  932.  
  933. return
  934.  
  935.  
  936. Parse_Cfg_Args: procedure Expose cfg. system.
  937.  
  938.     parse arg args, tpl, cfgkey, l
  939.  
  940.     args    = strip(translate(args, '  ', '9'x'='))
  941.  
  942.     pk        = pos('/K', tpl)
  943.     ps        = pos('/S', tpl)
  944.  
  945.     select
  946.         when pk=0    & ps=0    then    p    = 0
  947.         when pk=0 & ps>0    then  p    = ps
  948.         when ps=0 & pk>0    then    p    = pk
  949.         otherwise                                p    = min(pk, ps)
  950.     end
  951.  
  952.     p            = lastpos(',', left(tpl, p))
  953.     tpl        = substr(tpl',', p+1) || left(tpl, max(p-1, 0))
  954.  
  955.     do while tpl~=''
  956.         parse var tpl template ',' tpl
  957.         parse var template keyword '/' .
  958.  
  959.         bool    = pos('/S',    template)>0
  960.         key        = pos('/K', template)>0
  961.         must    = pos('/A', template)>0
  962.         num        = pos('/N', template)>0
  963.  
  964.         select
  965.             when must then        cfg.prm.keyword    = '0'x
  966.             when bool    then        cfg.prm.keyword    = 0
  967.             when num    then        cfg.prm.keyword    = 0
  968.  
  969.             otherwise                    cfg.prm.keyword    = ''
  970.         end
  971.  
  972.         if bool | key    then    mode    = ~bool
  973.         else                mode    = 2
  974.  
  975.         cfg.prm.keyword    = Get_Arg(keyword, mode, cfg.prm.keyword)
  976.  
  977.         if must & cfg.prm.keyword='0'x then call Quit(15, template 'for' cfgkey 'missing at line' l)
  978.  
  979.         if num & ~datatype(cfg.prm.keyword, 'N') then
  980.             if ~must & cfg.prm.keyword='' then    cfg.prm.keyword    = 0
  981.             else call Quit(15, 'Numeric value expected for'cfgkey template' at line' l', but is "'cfg.prm.keyword'"!!!')
  982.     end
  983.  
  984.     if args~='' then call Quit(10, 'Unknown option(s) "'args'" for' cfgkey 'at line' l'!!!')
  985.  
  986. return
  987.  
  988.  
  989. Read_Cfg: procedure Expose system.
  990.  
  991.     parse value statef(system.prg.script) with . size . . . . . version cfg_crc scr_crc
  992.  
  993.     MM_CRCFile system.prg.cfg 'crc'
  994.  
  995.     if system.nocpl | x2c(version)=system.prg.ver & crc=cfg_crc & ~system.arg.cplcfg then
  996.         do
  997.             MM_CRCFile system.prg.script 'crc'
  998.  
  999.             if system.nocpl | crc=scr_crc then
  1000.                 do
  1001.                     call Log(' Reading config...')
  1002.                     call Cfg
  1003.  
  1004.                     return
  1005.                 end
  1006.         end
  1007.  
  1008.     call Compile_Cfg
  1009.  
  1010. return
  1011.  
  1012.  
  1013.                                  /*** CFG ***/
  1014.  
  1015.  
  1016. Cfg:
  1017.  
  1018. return
  1019.  
  1020.